package com.example.page;

import com.vaadin.flow.component.Component;
import com.vaadin.flow.component.UI;
import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.html.Label;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.component.select.Select;
import com.vaadin.flow.component.textfield.TextField;

import java.util.ArrayList;
import java.util.List;

public abstract class PageComponent extends VerticalLayout {
    //当前页
    protected int curPage;

    // 总页数
    protected int pageSize;

    // 总条数
    protected int tolNum;

    // 每页显示条数
    protected int tolPage;

    protected int starPage;

    protected int endPage;

    protected int nowPage;

    protected Label tolNumLabel, label1, label2;

    protected Select<String> pageSelect;

    protected Button nextPage;

    protected Button previous;

    protected TextField toPage;

    protected Label[] labels;

    protected Button firstPage;

    protected Button lastPage;

    protected Button go;

    protected String selectValue;

    protected HorizontalLayout hor;

    public List<Component> components;

    protected Select<String> pageSizeNum;

    protected String pageSizeValue = "1—10页";

    public PageComponent(){
        this.selectValue = tolPage + "条/页";
        this.hor = new HorizontalLayout();
        this.components = new ArrayList<>();
    }

    public PageComponent(int curPage, int pageSize, int tolNum, int tolPage){
        this.tolNum = tolNum;
        this.pageSize = pageSize;
        this.nowPage = this.starPage = this.curPage = curPage;
        this.tolPage = tolPage;

        this.selectValue = tolPage + "条/页";
        this.hor = new HorizontalLayout();
        this.components = new ArrayList<>();

        this.init();
    }

    protected void setPageSelect(){
        String[] pages = new String[]{"2条/页", "3条/页", "5条/页", "7条/页", "10条/页", "15条/页"};
        pageSelect = new Select<>(pages);
        pageSelect.setValue(selectValue);
        pageSelect.setWidth("100px");

        this.pageSelect.addValueChangeListener(e->{
            nowPage = starPage = curPage = 1;
            selectValue = pageSelect.getValue();
            pageSize = Integer.parseInt(selectValue.substring(0, selectValue.indexOf("条")));
            double num = Double.parseDouble(tolNum+"") / Double.parseDouble(pageSize + "");
            tolPage = (int) (Math.ceil(num));
            System.out.println(tolPage);
            this.selectPage();
            this.init();
        });
    }

    protected void setLabel(){
        tolNumLabel = new Label("共" + tolNum + "条");
        label1 = new Label("前往");
        label2 = new Label("页");
        label1.getStyle().set("margin-top", "10px");
        label2.getStyle().set("margin-top", "10px");
        tolNumLabel.getStyle().set("margin-top", "10px");
    }

    protected void setButton(){
        nextPage = new Button(">");
        previous = new Button("<");
        firstPage = new Button("第一页");
        lastPage = new Button("最后一页");
        go = new Button("go");

        nextPage.addClickListener(e->{
            if(nowPage < endPage){
                labels[nowPage - 1].getStyle().set("color", "white");
                curPage++;
                nowPage++;
                labels[nowPage - 1].getStyle().set("color", "green");
                this.pagePrevious();
            }
        });

        previous.addClickListener(e->{
            if(nowPage > starPage){
                labels[nowPage - 1].getStyle().set("color", "white");
                curPage--;
                nowPage--;
                labels[nowPage - 1].getStyle().set("color", "green");
                this.pageNext();
            }
        });

        this.go.addClickListener(e->{
            try {
                int num = Integer.parseInt(toPage.getValue());
                if(num > Integer.parseInt(labels[labels.length - 1].getText()) || num < Integer.parseInt(labels[0].getText())){
                    throw new RuntimeException("页数范围必须是"+labels[0].getText() +" — " + labels[labels.length - 1].getText());
                }else {
                    labels[nowPage - 1].getStyle().set("color", "white");
                    curPage = num;
                    labels[nowPage - 1].getStyle().set("color", "green");
                    this.gotoPage();
                }
            }catch (NumberFormatException exception){
                UI.getCurrent().getPage().executeJs("alert('只能输入数字')");
            }catch (RuntimeException r){
                UI.getCurrent().getPage().executeJs("alert('" + r.getMessage() + "')");
            }
        });

        this.firstPage.addClickListener(e->{
            labels[curPage - 1].getStyle().set("color", "white");
            curPage = starPage;
            nowPage = starPage;
            labels[curPage - 1].getStyle().set("color", "green");
            this.firstPage();
        });

        this.lastPage.addClickListener(e->{
            labels[curPage - 1].getStyle().set("color", "white");
            curPage = endPage;
            nowPage = endPage;
            labels[curPage - 1].getStyle().set("color", "green");
            this.lastPage();
        });
    }

    protected void setInput(){
        toPage = new TextField();
        toPage.setWidth("50px");
    }

    protected void setPageSizeNum(){
        int size = (int) Math.ceil(Double.parseDouble(pageSize+"") / Double.parseDouble("10"));
        String[] values = new String[size];
        for (int i = 0; i < size; i++) {
            values[i] = (((i * 10)+1) + "—" + ((i+1) * 10) + "页");
        }

        pageSizeNum = new Select<>(values);
        pageSizeNum.setWidth("100px");
        pageSizeNum.setValue(pageSizeValue);

        pageSizeNum.addValueChangeListener(e->{
            curPage = Integer.parseInt(pageSizeNum.getValue().substring(0, pageSizeNum.getValue().indexOf("—")));
            starPage = 1;
            nowPage = starPage;
            endPage = curPage + 9;
            pageSizeValue = pageSizeNum.getValue();
            init();
        });
    }

    public void init(){
        this.setButton();
        this.setInput();
        this.setLabel();
        this.setPageSelect();
        this.setLabels();
        this.setPageSizeNum();

        this.removeAll();
        hor.removeAll();

        hor.add(tolNumLabel, pageSelect, firstPage, previous);

        for (Label label : labels) {
            hor.add(label);
        }

        hor.add(nextPage, lastPage, pageSizeNum, label1, toPage, label2, go);

        for (Component component : components) {
            this.add(component);
        }
        this.add(hor);
    }

    protected void setLabels(){
        try {
            endPage = Math.min(tolPage - (starPage - 1), 10);
            labels = new Label[endPage];
            int num = starPage;
            for (int i = 0; i < labels.length; i++) {
                labels[i] = new Label(num++ + "");
                labels[i].getStyle().set("margin-top", "10px");
            }
            labels[nowPage - 1].getStyle().set("color", "green");
        } catch (Exception exception) {
//            exception.printStackTrace();
        }
    }

    protected abstract void pageNext();

    protected abstract void pagePrevious();

    protected abstract void gotoPage();

    protected abstract void firstPage();

    protected abstract void lastPage();

    protected abstract void selectPage();
}